package Connection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * This database manager makes connection to a database. You are in need of a
 * database connector. These jars are downloadable from a database website.
 * import the downloaded library into your project.
 *
 * @author Kenneth Veenstra
 * @version 0.1
 */
public class DatabaseConnection
{
    private DatabaseConnection instance;
    private Connection connection = null;
    private String driverString;
    private String connectorString;
    private String databaseHost = "localhost";
    private String databasePort = "3306";
    private String databaseLogin = "root";
    private String databasePassword = "sqlroot";
    private String databaseName = "game";

    public DatabaseConnection()
    {
        this.connectorString = "jdbc:mysql://";
        this.driverString = "com.mysql.jdbc.Driver";
    }

    /**
     * Get the instance van de database manager (singleton).
     *
     * @return DatabaseManager
     */
    public synchronized DatabaseConnection getInstance()
    {
        if ( instance == null )
        {
            instance = new DatabaseConnection();
        }
        return instance;
    }

    /**
     * This method pretends a clone of this object.
     *
     * @exception CloneNotSupportedException Cloning this instance is not
     *                                       allowed.
     */
    @Override
    public Object clone() throws CloneNotSupportedException
    {
        throw new CloneNotSupportedException();
    }

    /**
     * With this method, you can connect to a database.
     *
     * @param databaseHost     The host of the database.
     * @param databasePort     The port of the database.
     * @param databaseLogin    The login for the database.
     * @param databasePassword The password for the database.
     * @param databaseName     The database name you want to use.
     *
     * @throws ConnectionFailedException Failed to create a connection.
     */
    public void connect(String databaseHost, String databasePort,
            String databaseLogin, String databasePassword, String databaseName)
            throws Exception
    {
        this.databaseHost = databaseHost;
        this.databasePort = databasePort;
        this.databaseLogin = databaseLogin;
        this.databasePassword = databasePassword;
        this.databaseName = databaseName;
        connect();
    }

    /**
     * Tries to make a connection, this method is special for the exception
     * catch.
     *
     * @throws Exception Failed to create a connection.
     */
    private void connect() throws Exception
    {
        try
        {
            connection = createConnection();
        }
        catch ( Exception e )
        {
            throw e;
        }
    }

    /**
     * Creates a connection with the driver.
     *
     * @return Connection A connection to a database
     *
     * @throws SQLException
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @see java.sql.Connection
     */
    private Connection createConnection() throws SQLException,
            ClassNotFoundException, IllegalAccessException,
            InstantiationException
    {
        if ( driverString != null )
        {
            try
            {
                Class.forName(driverString).newInstance();
                return DriverManager.getConnection(connectorString
                        + databaseHost + ":" + databasePort + "/"
                        + databaseName, databaseLogin, databasePassword);
            }
            catch ( InstantiationException e )
            {
                throw e;
            }
            catch ( IllegalAccessException e )
            {
                throw e;
            }
            catch ( ClassNotFoundException e )
            {
                throw e;
            }
        }
        return null;
    }

    /**
     * Get the connection.
     *
     * @return Connection A connection to a database
     *
     * @see java.sql.Connection
     */
    public Connection getConnection()
    {
        return connection;
    }

    /**
     * Closes the connection.
     */
    public void closeConnection()
    {
        try
        {
            connection.close();
            connection = null;
        }
        catch ( SQLException e )
        {
            /* connection already closed or doesn't exist anymore */
        }
    }

    /**
     * Closes the connection delete the database manager instance.
     */
    public void deleteInstance()
    {
        closeConnection();
        instance = null;
    }

    public void executeQuery(String s)
    {
        System.out.println(s);
        try
        {
            connect();
            PreparedStatement ppstm = makePreparedStatement(s);
            ppstm.execute();
            closeConnection();
        }
        catch ( Exception ex )
        {
            ex.printStackTrace();
        }
    }

    public PreparedStatement makePreparedStatement(String statement)
    {
        PreparedStatement ppstm = null;
        try
        {
            if ( connection != null || !connection.isClosed() )
            {
                ppstm = connection.prepareStatement(statement);
            }
            return ppstm;
        }
        catch ( SQLException e )
        {
            e.printStackTrace();
        }
        return ppstm;
    }
}
